#pragma once

#include <boost/shared_ptr.hpp>
#include "GetEphemInterface.h"
#include "Integrator.h"

class CApproach
{
public:
	typedef boost::shared_ptr<CApproach> Ptr;
public:
	CApproach(eBodies bodyNum, double dTime, const Body &body, double dXdiff[3], double dParam);
	virtual ~CApproach(void);
	double Dist() const;

	static bool CompareApproachesByTime(Ptr a, Ptr b);
	static bool CompareApproachesByTimeParam(Ptr a, Ptr b);
protected:
public:
	eBodies		m_bodyNum;
	double		m_dTime;
	Body		m_body;
	double		m_dXdiff[3];
	double		m_dDist;
	double		m_dParam;
};

typedef list<CApproach::Ptr> ListApproachPtr;

class CTraceApproaches
{
public:
	typedef boost::shared_ptr<CTraceApproaches> Ptr;
public:
	CTraceApproaches(double dParam, ListApproachPtr &appList) // list will be cleaned
	: m_dParam(dParam)
	{
		m_appList.swap(appList);
	}
	double			m_dParam;
	ListApproachPtr	m_appList;
};


class COneBodyApproachSearcher
{
public: 
	COneBodyApproachSearcher(ISimpleIntegratorInterface * pIntegrator, IGetCoord * pEphem, eBodies nBodyNum, double dParam);
	
	CApproach::Ptr Check(double dTime, const Body & body);
protected:
	double GetDistance(double dTime, const Body & body, double dXdiff[3]);
	CApproach::Ptr Search(double dTime, Body body, double dStep);
protected:
	double			m_dDetectDist;
	eBodies			m_nBodyNum;
	double			m_dPrevDist;
	double			m_dPrevTime;
	bool			m_bWasApproach;
	ISimpleIntegratorInterface * m_pIntegrator;
	IGetCoord *		m_pEphem;
	double			m_dSerchAccuracy;
	double			m_dParam;
};

typedef list<COneBodyApproachSearcher> ListApprchSch;

class CApproachSearcher
{
public:
	CApproachSearcher(ISimpleIntegratorInterface * pIntegrator, IGetCoord * pEphem, const vector<eBodies> & vecBodysToSearch, double dParam);
	ListApproachPtr Check(double dTime, const Body & body);
protected:
	ListApprchSch	m_listSearcher;
};


class CGridParam;
class IDrawInterface
{
public:
	virtual bool LoadGridParam ( CGridParam * gp ) = 0;
	virtual bool AppendApproaches(ListApproachPtr &ListOut) = 0;
};

class IApproachHolder
{
public:
	virtual bool AppendTraceApproaches(CTraceApproaches::Ptr listApprc) = 0;
	virtual bool GetApproachesInRange(const CGridParam &ranges, ListApproachPtr &ListOut) = 0;

};